//
// File:	Engine.cpp
// Author:	Thomas TISSOT-DUPONT
// Login:	<thomas.tissotdupont@free.fr>
//
// Create:	26/01/2010 at 08:06:28
// Purpose:	
//
#include <QtGui/QApplication>
#include "Base.hpp"
#include "Engine.hpp"
#include "DisplayManager.hpp"
#include "InputManager.hpp"
#include "ResourceManager.hpp"
#include "ResourceManagerTypes.hpp"
#include "Level.hpp"
#include "Trace.hpp"

//------------------------------------------------------------------
// Constructor / Destructor
//------------------------------------------------------------------
Engine::Engine()
	:	m_bRunning(false),
		m_bInGame(false)
{
}

Engine::~Engine()
{
}

//------------------------------------------------------------------
// Start
//------------------------------------------------------------------
bool Engine::Start()
{
	if (m_bRunning)
		return false;
	m_bRunning = true;
	GlobalVariables::DisplayManager::Get().Start();
	GlobalVariables::GuiManager::Get().SetVisible(true);
	GlobalVariables::DisplayManager::Get().SetActive(false);
	Trace::debug << "Engine::Start" << std::endl;
	return true;
}

//------------------------------------------------------------------
// Stop
//------------------------------------------------------------------
bool Engine::Stop()
{
	if (!m_bRunning)
		return false;
	m_bRunning = false;
	GlobalVariables::DisplayManager::Get().Stop();
	Trace::debug << "Engine::Stop" << std::endl;
	return true;
}

//------------------------------------------------------------------
// Run
//------------------------------------------------------------------
void Engine::Run()
{
	while (m_bRunning)
	{
		GlobalVariables::Global::Get().Update();
		GlobalVariables::InputManager::Get().Update();
		if (GlobalVariables::InputManager::Get().HasInput("menu"))
		{
			GlobalVariables::DisplayManager::Get().SetActive(false);
			GlobalVariables::GuiManager::Get().SetVisible(true);
		}

		//Update the GUI if it is visible
		if (GlobalVariables::GuiManager::Get().IsVisible())
		{
			if (GlobalVariables::GuiManager::Get().GetCurrentPanel() != NULL)
				GlobalVariables::GuiManager::Get().GetCurrentPanel()->Update();
		}

		//Update the entities and the gamerules if we are in-game
		if (m_bInGame)
		{
			GlobalVariables::SoundManager::Get().RemoveDeletedSounds();
			GlobalVariables::EntityManager::Get().RemoveUnusedEntities();
			GlobalVariables::EntityManager::Get().UpdatePreEntities();
			GlobalVariables::GameRuleManager::Get().Update();
			GlobalVariables::EntityManager::Get().UpdatePostEntities();
			GlobalVariables::SoundManager::Get().Update();
			GlobalVariables::EventManager::Get().Update();
		}

		//Process Events
		QApplication::processEvents();
	}
}

//------------------------------------------------------------------
// In Game
//------------------------------------------------------------------
bool Engine::IsInGame() const
{
	return m_bInGame;
}

void Engine::StartGame(const std::string &gameruleName, const std::string &levelName)
{
	m_bInGame = true;

	//Do we know this gamerule ?
	if (!GlobalVariables::GameRuleManager::Get().HasGameRule(gameruleName))
	{
		Trace::error << "Engine::StartGame: unknown gamerule: " << gameruleName << std::endl;
		StopGame();
		return;
	}

	//Load the level
	//TODO: we need to pass the mapname as the method parameter
	Level level;
	if (!level.LoadLevelFile("data/levels/" + gameruleName + "/" + levelName))
	{
		StopGame();
		return;
	}
	level.CreateWorld();
	level.CreateEntities();
	level.Clear();

	//Start Game Rules
	if (!GlobalVariables::GameRuleManager::Get().StartGameRule(gameruleName))
	{
		StopGame();
		return;
	}

	//Hide GUI and show renderer
	GlobalVariables::GuiManager::Get().SetVisible(false);
	GlobalVariables::DisplayManager::Get().SetActive(true);
}

void Engine::StopGame()
{
	m_bInGame = false;

	//Clear entities
	GlobalVariables::EntityManager::Get().Clear();

	//Clear ressources
	ImageResourceManager::GetInstance().ClearAll();
	SoundResourceManager::GetInstance().ClearAll();

	//Stop gamerules
	GlobalVariables::GameRuleManager::Get().StopGameRule();

	//Stop Events
	GlobalVariables::EventManager::Get().DisconnectAll();

	//Show GUI and hide renderer
	GlobalVariables::GuiManager::Get().SetVisible(true);
	GlobalVariables::DisplayManager::Get().SetActive(false);
}
